home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / intrvews / xgrab.lha / xgrab / ui / routines2.c < prev    next >
C/C++ Source or Header  |  1990-03-06  |  9KB  |  444 lines

  1. /**
  2.    GRAB Graph Layout and Browser System
  3.  
  4.    Copyright (c) 1986, 1988 Regents of the University of California
  5.    Copyright (c) 1989, Tera Computer Company
  6.  **/
  7.  
  8.   /**
  9.      routines2.c -- more fun menu routines, including most of the
  10.      statistics dumping routines and the checkpoint routines
  11.    **/
  12.  
  13. #include "malloc.h"
  14. #include <math.h>
  15.  
  16. #include "attribute.h"
  17. #include "digraph.h"
  18. #include "screen.h"
  19. #include "globals.h"
  20. #include "scrdep.h"
  21. #include "interf.h"
  22. #include "checkpoint.h"
  23. #include "cursor.h"
  24.  
  25. extern NODE *next_dummy();
  26.  
  27. void DoPrintDistributionStats();
  28.  
  29. DumpBox(b)
  30. BOX *b;
  31. {
  32.     printf("min_x=%d, max_x=%d, min_y=%d, max_y=%d",
  33.        b->min_x, b->max_x, b->min_y, b->max_y);
  34. }
  35.  
  36.   /**
  37.      For button area.  
  38.         Can't press buttons while moving or inserting.
  39.         Can press button while changing labels (just leave the current mode)
  40.    **/
  41.  
  42. BOOL GetInCTextModeFlag()
  43. {
  44.     return (inChangeTextMode);
  45. }
  46.  
  47. BOOL GetInCEdgeLabelModeFlag()
  48. {
  49.     return (inChangeEdgeLabelMode);
  50. }
  51.  
  52. BOOL GetInFNodeModeFlag()
  53. {
  54.     return (inFocusNodeMode);
  55. }
  56.  
  57. BOOL GetInCModeFlag()
  58. {
  59.     return (inChangeTextMode || inChangeEdgeLabelMode || inFocusNodeMode);
  60. }
  61.  
  62. void ClearInModeFlag()
  63. {
  64.     inChangeTextMode = FALSE;
  65.     inChangeEdgeLabelMode = FALSE;
  66.     inFocusNodeMode = FALSE;
  67. }
  68.  
  69. void DoPrintLayoutStats()
  70. {
  71.     printf("\n*XGRAB LAYOUT STATS*\n");
  72.     PrintNodeStats();
  73.     PrintEdgeStats();
  74.     PrintLevelStats();
  75.     PrintCrossingsStats();
  76.     DoPrintDistributionStats();
  77.     PrintAbsCoordStats();
  78. }
  79.  
  80. PrintNodeStats()
  81. {
  82.     NODE *node;
  83.     int dummyNodeCount, realNodeCount;
  84.  
  85.     dummyNodeCount = realNodeCount = 0;
  86.  
  87.     each_node(digraph, node)
  88.     loop
  89.     if (Is_dummy(node)) 
  90.     {
  91.         dummyNodeCount++;
  92.     }
  93.     else 
  94.     {
  95.         realNodeCount++;
  96.     }
  97.     endloop
  98.  
  99.     printf("total # of nodes: %d (real=%d;dummy=%d)\n", 
  100.        dummyNodeCount+realNodeCount, realNodeCount, dummyNodeCount);
  101. }
  102.  
  103. Length(fromMember, toMember)
  104. MEMBER *fromMember, *toMember;
  105. {
  106.     int xdist, ydist, dist;
  107.  
  108.     xdist = X_position(fromMember) - X_position(toMember);
  109.     ydist = Y_position(fromMember) - Y_position(toMember);
  110.     dist = (xdist * xdist) + (ydist * ydist);
  111.  
  112.     return((int) sqrt((double) dist));
  113. };
  114.  
  115. PrintEdgeStats()
  116. {
  117.     VNO toVno;        /* each succedent node */
  118.     NODE *node, *toNode;
  119.     int totalEdgeCount, shortEdgeCount, longEdgeCount, segmentCount;
  120.     int totalEdgeLength;
  121.  
  122.     totalEdgeCount = shortEdgeCount = longEdgeCount = segmentCount = 0;
  123.     totalEdgeLength = 0;
  124.  
  125.     each_node(digraph, node)
  126.     loop
  127.     if (Is_dummy(node)) 
  128.     {
  129.         continue;
  130.     }
  131.  
  132.     each_element(Succ_set(node), toVno)
  133.     loop
  134.         toNode = Node(digraph, toVno);
  135.         totalEdgeCount++;
  136.         totalEdgeLength += Length(Node_member(node), Node_member(toNode));
  137.  
  138.         if (!Is_dummy(toNode)) 
  139.         {
  140.         shortEdgeCount++;
  141.         segmentCount++;
  142.         }
  143.         else 
  144.         {
  145.         longEdgeCount++;
  146.         segmentCount++;
  147.         toNode = next_dummy(digraph, node);
  148.  
  149.         while (Is_dummy(toNode)) 
  150.         {
  151.             segmentCount++;
  152.             totalEdgeLength += Length(Node_member(node),
  153.             Node_member(toNode));
  154.             toNode = next_dummy(digraph, toNode);
  155.         }
  156.  
  157.         segmentCount++;
  158.         totalEdgeLength += Length(Node_member(node),
  159.             Node_member(toNode));
  160.         }
  161.     endloop
  162.     endloop
  163.  
  164.     printf("total # of edges: %d (short: %d, long: %d)\n", totalEdgeCount,
  165.        shortEdgeCount, longEdgeCount);
  166.     printf("total segments: %d\n", segmentCount);
  167.     printf("total edge length: %d\n", totalEdgeLength);
  168. }
  169.  
  170. #define MAX_LEV_ARRAY    512
  171.  
  172. PrintLevelStats()
  173. {
  174.     int i, count = 0;
  175.     LEVEL *level;
  176.     MEMBER *member;
  177.     double stdDev, mean, sum, diff;
  178.     int maxLevelCoord, median, levArray[MAX_LEV_ARRAY];
  179.  
  180.     if (!digraph->levels) 
  181.     {
  182.     printf("level stats unavailable - no level structure\n");
  183.     return;
  184.     }
  185.  
  186.     each_level(digraph, level) 
  187.     loop
  188.     each_member(level, member)
  189.     loop
  190.         if (count < MAX_LEV_ARRAY) 
  191.         {
  192.         levArray[count++] = Y_position(member);
  193.         }
  194.         else 
  195.         {
  196.         fprintf(stderr, "PrintLevelStats: outa room in levArray\n");
  197.         }
  198.         break;
  199.     endloop
  200.     endloop
  201.  
  202.       /* calc maxLevelCoord */
  203.     maxLevelCoord = levArray[0];
  204.  
  205.       /* calc median */
  206.     median = levArray[(count-1)/2];
  207.  
  208.       /* calc mean */
  209.     sum = 0.0;
  210.  
  211.     for (i = 0; i < count; i++) 
  212.     {
  213.     sum += levArray[i];
  214.     }
  215.  
  216.     mean = sum/(double)count;
  217.  
  218.       /* calc std dev */
  219.     sum = 0.0;
  220.  
  221.     for (i = 0; i < count; i++) 
  222.     {
  223.     diff = (double)levArray[i] - mean;
  224.     sum += diff * diff;
  225.     }
  226.  
  227.     sum = sum / (double) count;
  228.     stdDev = sqrt(sum);
  229.  
  230.     printf("# levels = %d; ", count);
  231.     printf("max = %d; median = %d; mean = %.2f; std dev = %.2f\n",
  232.        maxLevelCoord, median, mean, stdDev);
  233. }
  234.  
  235. PrintCrossingsStats()
  236. {
  237.     if (!digraph->levels) 
  238.     {
  239.     printf("crossings stats is unavailable - no level structure\n");
  240.     }
  241.     else 
  242.     {
  243.     printf("# of edge crossings = %d\n", num_crossings(digraph));
  244.     }
  245. }
  246.  
  247. #define MAX_XBINS 4
  248. #define MAX_YBINS 4
  249.  
  250. void DoPrintDistributionStats()
  251. {
  252.  
  253.     BOX absView;
  254.     NODE *node;
  255.     int bins[MAX_XBINS][MAX_YBINS];
  256.     int num_xbins, num_ybins, xbin, ybin, count, i, j;
  257.     float xDiv, yDiv, mean, diff, variance;
  258.  
  259.     printf("Node Spatial Distribution:\n");
  260.     FindRange(digraph, &absView);
  261.  
  262.     for (num_xbins = 1, num_ybins = 1;
  263.      num_xbins <= MAX_XBINS && num_ybins <= MAX_YBINS;
  264.          num_xbins++, num_ybins++)
  265.     {
  266.     xDiv = (absView.max_x - absView.min_x) / (float) num_xbins;
  267.     yDiv = (absView.max_y - absView.min_y) / (float) num_ybins;
  268.  
  269.     count = 0;
  270.     for (i = 0; i < num_xbins; i++)
  271.     {
  272.         for (j = 0; j < num_ybins; j++)
  273.         {
  274.         bins[i][j] = 0;
  275.         }
  276.     }
  277.  
  278.     each_node(digraph, node)
  279.     loop
  280.         if (!Is_dummy(node))
  281.         {
  282.         /*
  283.          * Compute the bin this node falls into, and increment count.
  284.          */
  285.         xbin = (X_position(Node_member(node)) - absView.min_x) / xDiv;
  286.         ybin = (Y_position(Node_member(node)) - absView.min_y) / yDiv;
  287.         bins[xbin][ybin]++;
  288.         count++;
  289.         }
  290.     endloop
  291.  
  292.     /*
  293.      * Calculate mean and variance for bins entries.
  294.      */
  295.     mean = (float) count / (num_xbins * num_ybins);
  296.     variance = 0.0;
  297.  
  298.     for (i = 0; i < num_xbins; i++)
  299.     {
  300.         for (j = 0; j < num_ybins; j++)
  301.         {
  302.         diff = (float) bins[i][j] - mean;
  303.         variance += diff * diff;
  304.         }
  305.     }
  306.  
  307.     variance = variance / (num_xbins * num_ybins);
  308.     printf("\t%d x %d bins, Var = %5.2f\n", num_xbins, num_ybins, variance);
  309.     }
  310. } /* DoPrintDistributionStats */
  311.  
  312. PrintAbsCoordStats()
  313. {
  314.     BOX absView;
  315.  
  316.     FindRange(digraph, &absView);
  317.     printf("absolute view bounding box: min_x=%d, min_y=%d, max_x=%d, max_y=%d\n",
  318.        absView.min_x, absView.min_y, absView.max_x, absView.max_y);
  319. }
  320.  
  321. void DoDumpNodeList()
  322. {
  323.     NODE *node;
  324.  
  325.     each_node(digraph, node)
  326.     loop
  327.         DumpNode(node);
  328.     endloop
  329. }
  330.  
  331. DumpNode(node)
  332.     NODE *node;
  333. {
  334.     printf("node=/%s/; vno=%d; x_pos=%d; y_pos=%d\n", 
  335.     Text(node), Vno(node), X_position(node), Y_position(node));
  336. }
  337.  
  338. DIGRAPH* copy_digraph();
  339.  
  340. DoSaveCkpt()
  341. {
  342.     int i;
  343.     char *buf;
  344.  
  345.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  346.     IChangeStatusLine("Saving current graph", TRUE);
  347.  
  348.     for (i = curr_ckpt + 1; i < num_ckpts; i++)
  349.     {
  350.     dispose_digraph(ckpts[i]->digraph);
  351.     dispose(ckpts[i]);
  352.     }
  353.  
  354.     create_checkpoint();
  355.     sprintf(buf, "Saved as checkpoint #%d", num_ckpts);
  356.     IChangeStatusLine(buf, FALSE);
  357.     ckpt_done = TRUE;
  358.     dispose(buf);
  359. }
  360.  
  361. create_checkpoint()
  362. {
  363.     curr_ckpt++;
  364.     num_ckpts = curr_ckpt + 1;
  365.  
  366.     if (num_ckpts != 1)
  367.     {
  368.         ckpts = (CHECKPT **) realloc((char *) ckpts, 
  369.                      num_ckpts * sizeof(CHECKPT *));
  370.     }
  371.     else
  372.     {
  373.     ckpts = (CHECKPT **) malloc(sizeof(CHECKPT *));
  374.     }
  375.  
  376.     new(ckpts[curr_ckpt], CHECKPT);
  377.     ckpts[curr_ckpt]->digraph = copy_digraph(digraph);
  378. }
  379.  
  380. DoPrevCkpt()
  381. {
  382.     char *buf;
  383.  
  384.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  385.     IChangeStatusLine("Going to previous checkpoint", TRUE);
  386.     ISetCursor(waitC);
  387.  
  388.     if (curr_ckpt > 0 || !ckpt_done && curr_ckpt == 0)
  389.     {
  390.         /* if we've changed the graph since the last checkpoint, just go back
  391.            to the current one, otherwise, go back one */
  392.         if (ckpt_done)
  393.         {
  394.         curr_ckpt--;
  395.         }
  396.     
  397.         dispose_digraph(digraph);
  398.         digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
  399.     DisplayNewGraph();
  400.         sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
  401.         IChangeStatusLine(buf, FALSE);
  402.         ckpt_done = TRUE;
  403.     }
  404.     else
  405.     {
  406.     IChangeStatusLine("No checkpoints before this one.", FALSE);
  407.     }
  408.  
  409.     IUnsetCursor();
  410.     dispose(buf);
  411. }
  412.  
  413. DoNextCkpt()
  414. {
  415.     char *buf;
  416.  
  417.     buf = (char *) malloc(sizeof(char) * MAXLINE);
  418.     IChangeStatusLine("Going to next checkpoint", TRUE);
  419.     ISetCursor(waitC);
  420.  
  421.     if (curr_ckpt + 1 < num_ckpts)
  422.     {
  423.     curr_ckpt++;
  424.     dispose_digraph(digraph);
  425.     digraph = copy_digraph(ckpts[curr_ckpt]->digraph);
  426.     DisplayNewGraph();
  427.         sprintf(buf, "Now at checkpoint #%d", curr_ckpt + 1);
  428.         IChangeStatusLine(buf, FALSE);
  429.         ckpt_done = TRUE;
  430.     }
  431.     else
  432.     {
  433.     IChangeStatusLine("No checkpoints after this one.", FALSE);
  434.     }
  435.  
  436.     IUnsetCursor();
  437.     dispose(buf);
  438. }
  439.  
  440. double GetAspRatio()
  441. {
  442.     return (double) aspratio;
  443. }
  444.